#include "TelephoneBook.h"
#include "TelephoneInfo.h"
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>

struct TelephoneBook
{
    ElementType *array; // 数组指针
    int capacity;       // 数组容量
    int size;           // 数组大小
};

void Interface(Telebook *t)
{
    printf("1.添加联系人\n");
    printf("2.删除联系人\n");
    printf("3.查找联系人\n");
    printf("4.修改联系人\n");
    printf("5.打印联系人信息\n");
    printf("6.模糊查询\n");
    printf("7.退出\n");
}

Telebook *InitTelebook()
{
    Telebook *t = (Telebook *)malloc(sizeof(Telebook));
    if (t == NULL)
    {
        printf("InitTelebook malloc error!\n");
        exit(-1);
    }
    t->size = 0;
    t->capacity = 10;
    t->array = (ElementType *)malloc(sizeof(ElementType) * t->capacity);
    if (t->array == NULL)
    {
        printf("InitTelebook array error!\n");
        exit(-1);
    }
    return t;
}

void InsertTelebook(Telebook *t)
{
    if (t->size == t->capacity)
    {
        t->capacity *= 2;
        t->array = (ElementType *)realloc(t->array, t->capacity * sizeof(ElementType));
        if (t->array == NULL)
        {
            printf("InitTelebook realloc error!\n");
            exit(-1);
        }
    }
    t->array[t->size] = CreateTelinfo();
    t->size++;
    printf("插入成功！\n");
    InsertSort(t, BiggerName);
}

void GetTxt(Telebook *t)
{
    FILE* f = fopen("./通讯录.txt","r");
    if(f == NULL)
    {
        printf("文件打开失败\n");
        return ;
    }
    
    fseek(f,0,SEEK_END);
    long len = ftell(f);
    printf("%ld\n",len);
    fseek(f,0,SEEK_SET);
    long size = ftell(f);
    while(size != len)
    {
        t->array[t->size++] = GetTelinfo(f);
        size = ftell(f);
    }
    fclose(f); 
}

//  读取结构体中的内容，再将其存入到电话本文档中即可

ElementType RemoveByIndex(Telebook *t, int index)
{
    ElementType result = t->array[index];
    for (int i = index; i < t->size - 1; i++)
    {
        t->array[i] = t->array[i + 1];
    }
    t->size--;
    RewriteToFile(t);
    return result;
}

void RemoveTelebook(Telebook *t, bool (*compare)(ElementType, ElementType))
{
    bool flag = false;
    printf("请输入要移除的用户名字/电话号码: \n");
    getchar();
    char value[15];
    scanf("%s", value);
    for (int i = 0; i < t->size; i++)
    {
        if (compare(t->array[i], value))
        {
            flag = true;
            ClearTelinfo(t->array[i]);
            // free(t->array[i]);
            RemoveByIndex(t, i);
        }
    }
    if (flag)
    {
        printf("删除联系人成功!\n");
        RewriteToFile(t);
    }
    else
    {
        printf("未查询到相关信息!\n");
    }
    getchar();
    getchar();
}

int BinarySearch(Telebook *t, int (*compare)(ElementType, ElementType))
{
    printf("请输入要查找的用户姓名: \n");
    char value[15];
    scanf("%s", value);
    int left = 0;
    int right = t->size;
    while (left <= right)
    {
        int mid = left + (right - left) / 2;
        if (compare(t->array[mid], value) == 0)
        {
            return mid;
            // PrintTelinfo(t->array[mid]);
            // break;
        }
        else if (compare(t->array[mid], value) > 0)
        {
            right = mid - 1;
        }
        else if (compare(t->array[mid], value) < 0)
        {
            left = mid + 1;
        }
    }
    return -1;
}

void FindByElement(Telebook *t, bool (*compare)(ElementType, ElementType))
{
    int index = BinarySearch(t, FindEqual);
    if (index >= 0)
    {
        for (int i = 0; i < t->size; i++)
        {
            if (compare(t->array[i], t->array[index]))
            {
                printf("找到以下联系人信息：\n");
                PrintTelinfo(t->array[i]);
            }
        }
    }
    else
    {
        printf("未查询到相关联系人\n");
    }
    getchar();
    getchar();
}

void ModifyByElement(Telebook *t, bool (*compare)(ElementType, ElementType))
{
    bool flag = false;
    printf("请输入要修改的用户姓名/电话号码: \n");
    char value[15];
    scanf("%s", value);
    for (int i = 0; i < t->size; i++)
    {
        if (compare(t->array[i], value))
        {
            flag = true;
            ClearTelinfo(t->array[i]);
            // free(t->array[i]);
            t->array[i] = CreateTelinfo();
            break;
        }
    }
    
    if (!flag)
    {
        printf("未查询到相关信息\n");
    }
    getchar();
    getchar();
}

void FuzzyFind(Telebook *t, bool (*compare)(ElementType, ElementType))
{
    bool flag = false;
    printf("请输入要查找的用户姓名: \n");
    char value[15];
    scanf("%s", value);
    for (int i = 0; i < t->size; i++)
    {
        if (compare(t->array[i], value))
        {
            printf("找到以下联系人信息：\n");
            PrintTelinfo(t->array[i]);
            flag = true;
        }
    }
    if (!flag)
    {
        printf("未查询到相关联系人\n");
    }
    getchar();
    getchar();
}

void InsertSort(Telebook *t, int (*compare)(ElementType, ElementType))
{
    for (int i = 1; i < t->size; i++)
    {
        int j = i; // 这个位置是即将要插入的数
        int *temp = t->array[j];
        for (; j > 0; j--)
        {
            if (compare(t->array[j - 1], temp) > 0) // 前面的数比我大
            {
                t->array[j] = t->array[j - 1];
            }
            else // 前面的数不比我大
            {
                break;
            }
        }
        t->array[j] = temp;
    }
}

void PrintTelebook(Telebook *t, void (*print)(ElementType))
{
    if (t->size == 0)
    {
        printf("通讯录没有联系人信息");
    }
    else
    {
        printf("请选择排序方式:1.正向排序 2.逆向排序\n");
        int n = 0;
        scanf("%d", &n);
        printf("联系人信息: \n");
        if (n == 1)
        {
            for (int i = 0; i < t->size; i++)
            {
                print(t->array[i]);
            }
        }
        else if (n == 2)
        {
            for (int i = t->size - 1; i >= 0; i--)
            {
                print(t->array[i]);
            }
        }
        else
        {
            printf("输入错误\n");
        }
        printf("\n");
    }
    getchar();
    getchar();
}

void ClearTelebook(Telebook *t, void (*clear)(ElementType))
{
    if (t != NULL)
    {
        for (int i = 0; i < t->size; i++)
        {
            clear(t->array[i]);
        }
        free(t->array);
        free(t);
    }
}
